﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media;

namespace Dotway.WPF.Controls.Utilities
{
    internal static class Rgb2HsvConverter
    {
        #region Rgb To Hsv

        public static HSV Rgb2Hsv(Color color)
        {
            RGB rgb = new RGB(color);
            return Rgb2Hsv(rgb);
        }

        public static HSV Rgb2Hsv(RGB rgb)
        {            
            double max = Math.Max(rgb.R, Math.Max(rgb.G, rgb.B));
            double min = Math.Min(rgb.R, Math.Min(rgb.G, rgb.B));

            double h = Rgb2H(rgb);

            double s = 0.0;
            if (max == 0)
            {
                s = 0;
            }
            else
            {
                s = 1 - (min / max);
            }

            double v = max;

            HSV hsv = new HSV();
            hsv.H = h;
            hsv.S = s;
            hsv.V = v;

            return hsv;
        }

        public static Color H2Rgb(double h)
        {
            HSV hsv = new HSV(h, 1.0, 1.0);
            RGB rgb = Hsv2Rgb(hsv);
            return Color.FromRgb((byte)(rgb.R * 255.0),(byte)(rgb.G * 255.0), (byte)(rgb.B * 255.0));
        }

        public static double Color2H(Color color)
        {
            RGB rgb = new RGB(color);
            return Rgb2H(rgb);
        }

        public static double Rgb2H(RGB rgb)
        {
            double h = 0.0;
            double max = Math.Max(rgb.R, Math.Max(rgb.G, rgb.B));
            double min = Math.Min(rgb.R, Math.Min(rgb.G, rgb.B));

            if (max == min)
            {
                h = 0.0;
            }
            else if (max == rgb.R)
            {
                h = (60.0 * ((rgb.G - rgb.B) / (max - min))) % 360.0;

                if (rgb.G < rgb.B)
                {
                    h = 360.0 + h;
                }
            }
            else if (max == rgb.G)
            {
                h = 60.0 * ((rgb.B - rgb.R) / (max - min)) + 120.0;
            }
            else if (max == rgb.B)
            {
                h = 60.0 * ((rgb.R - rgb.G) / (max - min)) + 240.0;
            }

            return h;
        }

        #endregion Rgb To Hsv
        #region Hsv To Rgb

        public static RGB Hsv2Rgb(HSV hsv)
        {
            double hi = Math.Floor(hsv.H / 60.0) % 6;
            double f = hsv.H / 60.0 - Math.Floor(hsv.H / 60.0);
            double p = hsv.V * (1 - hsv.S);
            double q = hsv.V * (1 - f * hsv.S);
            double t = hsv.V * (1 - (1 - f) * hsv.S);

            RGB color = new RGB();
            if (hi == 0)
            {
                color.R = hsv.V;
                color.G = t;
                color.B = p;
            }
            else if (hi == 1)
            {
                color.R = q;
                color.G = hsv.V;
                color.B = p;
            }
            else if (hi == 2)
            {
                color.R = p;
                color.G = hsv.V;
                color.B = t;
            }
            else if (hi == 3)
            {
                color.R = p;
                color.G = q;
                color.B = hsv.V;
            }
            else if (hi == 4)
            {
                color.R = t;
                color.G = p;
                color.B = hsv.V;
            }
            else if (hi == 5)
            {
                color.R = hsv.V;
                color.G = p;
                color.B = q;
            }

            return color;
        }

        #endregion Hsv To Rgb
    }
}
